home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 1 / PC Actual CD 01.iso / f1 / cimb.arj / TIFF.C < prev    next >
Encoding:
C/C++ Source or Header  |  1994-10-19  |  16.9 KB  |  710 lines

  1. #include <stdio.h>
  2. #include <alloc.h>
  3. #include <dos.h>
  4. #include <string.h>
  5.  
  6. #include "global.h"
  7. #include "memoria.h"
  8. #include "video.h"
  9. #include "tiff.h"
  10. #include "error.h"
  11.  
  12.     /* Nombres de las etiquetas, estan todas las de la version TIFF 5.00 */
  13. #define NewSubfileType                254
  14. #define SubfileType                        255
  15. #define ImageWidth                        256
  16. #define ImageLength                        257
  17. #define BitsPerSample                    258
  18. #define Compression                        259
  19. #define PhotometricInterp            262
  20. #define Threshholding                    263
  21. #define CellWidth                            264
  22. #define CellLength                        265
  23. #define FillOrder                            266
  24. #define DocumentName                    269
  25. #define ImageDescription            270
  26. #define Make                                    271
  27. #define Model                                    272
  28. #define StripOffsets                    273
  29. #define Orientation                        274
  30. #define SamplesPerPixel                277
  31. #define RowsPerStrip                    278
  32. #define StripByteCounts                279
  33. #define MinSampleValue                280
  34. #define MaxSampleValue                281
  35. #define XResolution                        282
  36. #define YResolution                        283
  37. #define PlanarConfiguration        284
  38. #define Pagename                            285
  39. #define XPosition                            286
  40. #define YPosition                            287
  41. #define FreeOffsets                        288
  42. #define FreeByteCounts                289
  43. #define GrayResponseUnit            290
  44. #define GrayResponseCurve            291
  45. #define Group3Options                    292
  46. #define Group4Options                    293
  47. #define ResolutionUnit                296
  48. #define PageNumber                        297
  49. #define ColorResponseUnit            300
  50. #define ColorResponseCurves        301
  51. #define Software                             305
  52. #define DateTime                             306
  53. #define Artist                                 315
  54. #define HostComputer                     316
  55. #define Predictor                         317
  56. #define WhitePoint                         318
  57. #define PrimaryChromaticities 319
  58. #define Colormap                             320
  59.  
  60.     /* tipos de tags */
  61. #define TIFFbyte            1
  62. #define TIFFascii            2
  63. #define TIFFshort            3
  64. #define TIFFlong            4
  65. #define TIFFrational    5
  66.  
  67.     /* Tipos de compresion de ficheros */
  68. #define COMPno      1                /* sin comprimir                        */
  69. #define COMPhuff    2                /* CCITT 3, Metodo Huffman    */
  70. #define COMPfax3    3                /* Facsimile CCITT group 3    */
  71. #define COMPfax4    4       /* Facsimile CCITT group 4    */
  72. #define COMPlzw        5                /* LZW                                            */
  73. #define COMPmpnt    0x8005  /* PackBits o MacPaint            */
  74.  
  75.     /* clases de ficheros TIFF */
  76. #define TIFFclaseX 0        /* generico                    */
  77. #define TIFFclaseB 1        /* blanco y negro        */
  78. #define TIFFclaseG 2        /* gris                            */
  79. #define TIFFclaseP 3         /* paleta de color    */
  80. #define TIFFclaseR 4        /* RGB                            */
  81.  
  82.     /* variables para albergar los valores de los tags */
  83. int TIFFclase;
  84. unsigned int TIFFancho=0,TIFFalto=0,TIFFbytes=0;
  85. unsigned int TIFFformato=0;
  86. unsigned int TIFFsubfile=0;
  87. unsigned int TIFFsamples=1;
  88. unsigned int TIFFbitspersample=1;
  89. unsigned int TIFFplancfg=1;
  90. unsigned int TIFFcompres=1;
  91. unsigned int TIFFphotmet=0;
  92. unsigned long TIFFrowstrip=0L;
  93. unsigned long TIFFstripoff=0L;
  94. unsigned long TIFFstripcnt=0L;
  95. int TIFFcolores;
  96. char *TIFFpaleta = NULL;
  97.  
  98. IMAGEN *TIFFleerCabecera(IMAGEN *c,FILE *f,char *nombre);
  99. int TIFFleerTag(FILE *f);
  100. int TIFFleerclase(void);
  101. IMAGEN *TIFFleerImagen(IMAGEN *c,FILE *f);
  102. int TIFFleerLinea(char *p,FILE *f,int bytes);
  103. unsigned long TIFFleerLong(FILE *f);
  104. unsigned int TIFFleerWord(FILE *f);
  105.  
  106. void TIFFescribirCabecera(FILE *f);
  107. void TIFFescribirDirectorio(IMAGEN *c,FILE *f,long LugarDirectorio,long LugarPaleta,long LugarImagen);
  108. void TIFFescribirTAG(FILE *f,int tag,int tipo,long longitud,long desplazamiento);
  109. void TIFFescribirImagen(IMAGEN *c,FILE *f);
  110. void TIFFescribirLinea(char *p,FILE *f,int bytes);
  111. void TIFFescribirWord(FILE *f,int n);
  112. void TIFFescribirLong(FILE *f,long n);
  113.  
  114. extern IMAGEN *TIFFcargar(char *nombre,IMAGEN *c)
  115. {
  116.     /* puntero al fichero */
  117. FILE *f;
  118.  
  119.     /* abrir el fichero */
  120. if((f=fopen(nombre,"rb"))!=NULL)
  121.     {
  122.         /* leer cabecera */
  123.     if((c=TIFFleerCabecera(c,f,nombre))!=NULL)
  124.         /* leer imagen */
  125.         c = TIFFleerImagen(c,f);
  126.     fclose(f);
  127.     }
  128. else
  129.     {
  130.     ERRORponer(ERRapertura);
  131.     return(NULL);
  132.     }
  133. return(c);
  134. }
  135.  
  136. IMAGEN *TIFFleerCabecera(IMAGEN *c,FILE *f,char *nombre)
  137. {
  138.     /* contador */
  139. int i;
  140.     /* tags del directorio */
  141. unsigned int TIFFtotalTags=0;
  142.  
  143.     /* leer formato INTEL o MOTOROLA */
  144. TIFFformato=TIFFleerWord(f);
  145. if(TIFFformato != 'MM' && TIFFformato != 'II')
  146.     {
  147.     ERRORponer(ERRnoTratado);
  148.     return(NULL);
  149.     }
  150.  
  151.     /* comprobar que es un fichero TIFF */
  152. if(TIFFleerWord(f) != 42)
  153.     {
  154.     ERRORponer(ERRnoTratado);
  155.     return(NULL);
  156.     }
  157.  
  158.     /* posicionar para leer el primer IFD */
  159. fseek(f,TIFFleerLong(f),SEEK_SET);
  160.     /* leer los TAGs del IFD */
  161. TIFFtotalTags=TIFFleerWord(f);
  162. for(i=0;i<TIFFtotalTags;++i)
  163.     TIFFleerTag(f);
  164.  
  165.     /* si no se acepta el tipo de fichero o de compresion */
  166. if(TIFFsubfile || (TIFFcompres != COMPno && TIFFcompres != COMPmpnt))
  167.         {
  168.         ERRORponer(ERRnoTratado);
  169.         return(NULL);
  170.         }
  171.  
  172.     /* reservar memoria para la cabecera de trabajo */
  173. if((c=MEMreservarCAB(c))==NULL)
  174.     {
  175.     ERRORponer(ERRnoMemoria);
  176.     return(NULL);
  177.     }
  178.  
  179.     /* obtener el clase de fichero TIFF y cargar la cabecera de trabajo */
  180. TIFFclase = TIFFleerclase();
  181. switch(TIFFclase)
  182.     {
  183.         /* monocromo */
  184.     case TIFFclaseB:
  185.         c->colores = 2;
  186.         c->modo = VIDEOmono;
  187.         c->bytes = TIFFbytes;
  188.         c->haypaleta = FALSO;
  189.     break;
  190.  
  191.         /* color o tonos de gris */
  192.     case TIFFclaseG:
  193.     case TIFFclaseP:
  194.         c->colores = TIFFcolores;
  195.         c->modo = VIDEOvga;
  196.         c->bytes = TIFFbytes;
  197.             /* si hay paleta, leerla */
  198.         if(TIFFpaleta!= NULL)
  199.             {
  200.             memcpy(c->paleta,TIFFpaleta,c->colores*3);
  201.             free(TIFFpaleta);
  202.             c->haypaleta = CIERTO;
  203.             }
  204.         else
  205.             c->haypaleta = FALSO;
  206.     break;
  207.         /* RGB u otros */
  208.     default:
  209.         ERRORponer(ERRnoTratado);
  210.         c = MEMliberar(c);
  211.         return(c);
  212.     }
  213.  
  214.     /* cargar el resto de la cabecera de trabajo */
  215. strcpy(c->nombre,nombre);
  216. c->ancho = TIFFancho;
  217. c->alto =  TIFFalto;
  218. c->formato = TIFF;
  219.  
  220.     /* si no hay memoria para la imagen, liberar cabecera */
  221. if(!MEMreservar(c))
  222.     {
  223.     c = MEMliberar(c);
  224.     ERRORponer(ERRnoMemoria);
  225.     return(c);
  226.     }
  227. return(c);
  228. }
  229.  
  230. IMAGEN *TIFFleerImagen(IMAGEN *c,FILE *f)
  231. {
  232. long l;
  233. int i,j,b;
  234. char p[ANCHO_MAXIMO];
  235.  
  236. switch(TIFFclase)
  237.     {
  238.         /* monocroma */
  239.     case TIFFclaseB:
  240.             /* si hay un solo bloque */
  241.         if(TIFFstripcnt==1L)
  242.             {
  243.                 /* posicionar al inicio de la imagen */
  244.             fseek(f,TIFFstripoff,SEEK_SET);
  245.                 /* leer imagen */
  246.             for(i=0;i<c->alto;++i)
  247.                 {
  248.                 TIFFleerLinea(p,f,c->bytes);
  249.                 MEMescribir(p,i,c);
  250.                 }
  251.             }
  252.         else
  253.                 /* si son varios */
  254.             {
  255.             i=0;
  256.             for(l=0L;l<TIFFstripcnt;++l)
  257.                 {
  258.                     /* posicionar el puntero al inicio del bloque */
  259.                 fseek(f,TIFFstripoff+(l*sizeof(long)),SEEK_SET);
  260.                 fseek(f,TIFFleerLong(f),SEEK_SET);
  261.                     /* leer bloque */
  262.                 for(j = 0;j<TIFFrowstrip;j++)
  263.                     {
  264.                     TIFFleerLinea(p,f,c->bytes);
  265.                     MEMescribir(p,i++,c);
  266.                     }
  267.                 }
  268.             }
  269.     break;
  270.         /* color o gris */
  271.     case TIFFclaseP:
  272.     case TIFFclaseG:
  273.         if(TIFFbitspersample == 4)
  274.             b = c->bytes/2;
  275.         else
  276.             b = c->bytes;
  277.             /* si hay un solo bloque */
  278.         if(TIFFstripcnt==1L)
  279.             {
  280.                 /* posicionar puntero al inicio de la imagen */
  281.             fseek(f,TIFFstripoff,SEEK_SET);
  282.             for(i=0;i<c->alto;++i)
  283.                 {
  284.                 TIFFleerLinea(p,f,b);
  285.                 MEMescribir(p,i,c);
  286.                 }
  287.             }
  288.         else
  289.                 /* si hay varios bloques */
  290.             {
  291.             i=0;
  292.             for(l=0L;l<TIFFstripcnt;++l)
  293.                 {
  294.                     /* posicionar puntero al inicio del bloque */
  295.                 fseek(f,TIFFstripoff+(l*sizeof(long)),SEEK_SET);
  296.                 fseek(f,TIFFleerLong(f),SEEK_SET);
  297.                     /* leer bloque */
  298.                 for(j = 0;j<TIFFrowstrip;j++)
  299.                     {
  300.                     TIFFleerLinea(p,f,b);
  301.                     MEMescribir(p,i++,c);
  302.                     }
  303.                 }
  304.             }
  305.     break;
  306.     };
  307. return(c);
  308. }
  309.  
  310. int TIFFleerLinea(char *p,FILE *f,int bytes)
  311. {
  312. int i,n=0,c;
  313. char buffer[ANCHO_MAXIMO];
  314. memset(p,0,bytes);
  315. memset(buffer,0,ANCHO_MAXIMO);
  316.  
  317. switch(TIFFcompres)
  318.     {
  319.         /* sin comprimir */
  320.     case COMPno:
  321.             /* leer línea */
  322.         n=fread(buffer,1,bytes,f);
  323.             /* si es preciso, invertir línea */
  324.         if(TIFFphotmet==0)
  325.             for(i=0;i<bytes;++i)
  326.                 *(buffer+i)=~(*(buffer+i));
  327.             /* si hay 4 bits por pixel, extraer dos pixels de cada byte */
  328.         if(TIFFbitspersample == 4)
  329.             for(i=0,c=0;i<bytes;i++,c+=2)
  330.                 {
  331.                 p[c+1] = buffer[i] & 0x0f;
  332.                 p[c] = (buffer[i] & 0xf0) >> 4;
  333.                 }
  334.         else
  335.             memcpy(p,buffer,bytes);
  336.     break;
  337.  
  338.         /* Pacbits o MacPaint */
  339.     case COMPmpnt:
  340.         do
  341.             {
  342.                 /* leer byte */
  343.             c=fgetc(f) & 0xff;
  344.                 /* si el bit 7 es 1 */
  345.             if(c & 0x80)
  346.                 {
  347.                     /* contador */
  348.                 i=((~c) & 0xff)+2;
  349.                 c=fgetc(f);
  350.                 if(TIFFphotmet==0)
  351.                     while(i--)
  352.                         buffer[n++]=~c;
  353.                 else
  354.                     while(i--)
  355.                         buffer[n++]=c;
  356.                 }
  357.             else
  358.                 {
  359.                     /* contador */
  360.                 i=(c &0xff)+1;
  361.                 if(TIFFphotmet==0)
  362.                     while(i--)
  363.                         buffer[n++]=~fgetc(f);
  364.                 else
  365.                     while(i--)
  366.                         buffer[n++]=fgetc(f);
  367.                 }
  368.             }
  369.         while(n < bytes);
  370.             /* si hay 4 bits por pixel, extraer dos pixels de cada byte */
  371.         if(TIFFbitspersample == 4)
  372.             for(i=0,c=0;i<bytes;i++,c+=2)
  373.                 {
  374.                 p[c+1] = buffer[i] & 0x0f;
  375.                 p[c] = (buffer[i] & 0xf0) >> 4;
  376.                 }
  377.         else
  378.             memcpy(p,buffer,bytes);
  379.     break;
  380.     };
  381. return(n);
  382. }
  383.  
  384. int TIFFleerTag(FILE *f)
  385. {
  386.     /* numero del tag */
  387. int tag;
  388.     /* tipo de tag */
  389. int tipo;
  390.     /* longitud del tag */
  391. long longitud;
  392.     /* puntero al dato o valor */
  393. long desplazamiento;
  394.     /* contadores */
  395. int i,j;
  396.     /* puntero a paleta auxiliar */
  397. char *paux;
  398.  
  399.     /* leer número del tag */
  400. tag=TIFFleerWord(f);
  401.     /* leer tipo del tag */
  402. tipo = TIFFleerWord(f);
  403.     /* extraer longitud y desplazamiento (o valor) */
  404. switch(tipo)
  405.     {
  406.     case TIFFbyte:
  407.         longitud=(unsigned long)fgetc(f);
  408.         for(i=0;i<3;i++) fgetc(f);
  409.         desplazamiento=(unsigned long)fgetc(f);
  410.         for(i=0;i<3;i++) fgetc(f);
  411.     break;
  412.     case TIFFshort:
  413.         longitud=(unsigned long)TIFFleerWord(f);
  414.         TIFFleerWord(f);
  415.         desplazamiento=(unsigned long)TIFFleerWord(f);
  416.         TIFFleerWord(f);
  417.     break;
  418.     default:
  419.         longitud=TIFFleerLong(f);
  420.         desplazamiento=TIFFleerLong(f);
  421.     break;
  422.     };
  423.     /* tratar tag */
  424. switch(tag)
  425.     {
  426.     case NewSubfileType:TIFFsubfile=(unsigned int)desplazamiento;break;
  427.     case ImageWidth:TIFFancho=(unsigned int)desplazamiento;break;
  428.     case ImageLength:TIFFalto=(unsigned int)desplazamiento;break;
  429.     case RowsPerStrip:
  430.         /* filas por bloque */
  431.         if(tipo==TIFFlong)
  432.             TIFFrowstrip=desplazamiento;
  433.         else
  434.             TIFFrowstrip=desplazamiento & 0xffffL;
  435.     break;
  436.     case StripOffsets:
  437.         /* desplazamiento de bloque */
  438.         if(tipo==TIFFlong)
  439.             {
  440.             TIFFstripoff=desplazamiento;
  441.             TIFFstripcnt=longitud;
  442.             }
  443.         else
  444.             {
  445.             TIFFstripoff=desplazamiento & 0xffffL;
  446.             TIFFstripcnt=desplazamiento & 0xffffL;
  447.             }
  448.     break;
  449.     case SamplesPerPixel:TIFFsamples=(unsigned int)desplazamiento;break;
  450.     case BitsPerSample:TIFFbitspersample=(unsigned int )desplazamiento;break;
  451.     case PlanarConfiguration:TIFFplancfg=(unsigned int)desplazamiento;break;
  452.     case Compression:TIFFcompres=(unsigned int)desplazamiento;break;
  453.     case PhotometricInterp:TIFFphotmet=(unsigned int)desplazamiento;break;
  454.     case Colormap:
  455.         /* paleta de colores */
  456.         fseek(f,desplazamiento,SEEK_SET);
  457.         TIFFcolores = 1 << TIFFbitspersample;
  458.         TIFFpaleta = malloc(TIFFcolores*3);
  459.             /* leer las tres subcurvas */
  460.         for(j=0;j<3;j++)
  461.             {
  462.             paux = TIFFpaleta+j;
  463.                 /* los valores RGB vienen como enteros */
  464.             for(i=0;i<TIFFcolores;++i,paux+=3)
  465.                 {fgetc(f); *paux = fgetc(f);}
  466.             }
  467.     break;
  468.         /* tag desconocido o no tratado */
  469.     default:break;
  470.     };
  471. return(tag);
  472. }
  473.  
  474. int TIFFleerclase(void)
  475. {
  476.     /* clase no tratada */
  477. if(TIFFsamples!=1 || TIFFplancfg!=1)
  478.     return(TIFFclaseX);
  479.  
  480. switch(TIFFbitspersample)
  481.     {
  482.         /* monocromos, 1 bit por pixel */
  483.     case 1:
  484.         TIFFbytes = DePixelsABytes(TIFFancho);
  485.         TIFFcolores = 2;
  486.     return(TIFFclaseB);
  487.         /* gris o color, 4 u 8 bits por pixel */
  488.     case 4:
  489.     case 8:
  490.             /* determinar número de colores o grises */
  491.         TIFFcolores = 1 << TIFFbitspersample;
  492.         TIFFbytes = TIFFancho;
  493.             /* gris */
  494.         if(TIFFphotmet == 0 || TIFFphotmet == 1)
  495.             return(TIFFclaseG);
  496.             /* paleta de color */
  497.         else if(TIFFphotmet == 3)
  498.             return(TIFFclaseP);
  499.             /* RGB */
  500.         else if(TIFFphotmet == 2)
  501.             {
  502.             TIFFbytes = TIFFancho * 3;
  503.             return(TIFFclaseR);
  504.             }
  505.             /* desconocido o no tratado */
  506.         else return(TIFFclaseX);
  507.     default: return(TIFFclaseX);
  508.     };
  509. }
  510.  
  511. unsigned int TIFFleerWord(FILE *f)
  512. {
  513.     /* INTEL */
  514. if(TIFFformato == 'II')
  515.     return((fgetc(f) & 0xff) + ((fgetc(f) & 0xff) << 8));
  516.     /* MOTOROLA */
  517. else
  518.     return(((fgetc(f) & 0xff) << 8) + (fgetc(f) & 0xff));
  519. }
  520.  
  521. unsigned long TIFFleerLong(FILE *f)
  522. {
  523.     /* INTEL */
  524. if(TIFFformato == 'II')
  525.     return((unsigned long)(fgetc(f) & 0xff) +
  526.     ((unsigned long)(fgetc(f) & 0xff) << 8)+
  527.     ((unsigned long)(fgetc(f) & 0xff) << 16)+
  528.     ((unsigned long)(fgetc(f) & 0xff) << 24));
  529.     /* MOTOROLA */
  530. else
  531.     return(((unsigned long)(fgetc(f) & 0xff) << 24)+
  532.     ((unsigned long)(fgetc(f) & 0xff) << 16)+
  533.     ((unsigned long)(fgetc(f) & 0xff) << 8)+
  534.     (unsigned long)(fgetc(f) & 0xff));
  535. }
  536.  
  537.  
  538.     /* salvar un fichero TIFF */
  539. extern int TIFFsalvar(char *fichero,IMAGEN *c)
  540. {
  541.     /* puntero al fichero */
  542. FILE *f;
  543.     /* contadores */
  544. int i,j;
  545.     /* puntero auxiliar a paleta */
  546. char *paux;
  547.     /* desplazamientos */
  548. long TIFFlugarDirectorio;
  549. long TIFFlugarPaleta;
  550. long TIFFlugarImagen;
  551.     /* ajuste de colores */
  552. int colores;
  553.  
  554.     /* abrir el fichero */
  555. if((f = fopen(fichero, "wb")) == NULL)
  556.     {
  557.     ERRORponer(ERRapertura);
  558.     return(0);
  559.     }
  560.  
  561.     /* adecuar modo de video */
  562. if(c->modo == VIDEOvga && c->colores <= 16)
  563.     c = VIDEOvision(c);
  564.  
  565.     /* escribir la cabecera TIFF */
  566. TIFFescribirCabecera(f);
  567. TIFFlugarPaleta = ftell(f);
  568.  
  569.     /* si es de color, escribir paleta TIFF */
  570. if(c->modo != VIDEOmono)
  571.     {
  572.         /* ajustar colores */
  573.     colores = (c->modo == VIDEOega) ? 16 : 256;
  574.         /* escribir las 3 subcurvas */
  575.     for(j=0;j<3;j++)
  576.         {
  577.         paux = c->paleta+j;
  578.         for(i=0;i<colores;i++,paux+=3)
  579.             {
  580.                 /* cada componente ocupa dos bytes */
  581.             fputc(0,f);
  582.             fputc(*paux,f);
  583.             }
  584.         }
  585.     }
  586.  
  587.     /* escribir la imagen TIFF */
  588. TIFFlugarImagen = ftell(f);
  589. TIFFescribirImagen(c,f);
  590.     /* escribir directorio de TAGS */
  591. TIFFlugarDirectorio = ftell(f);
  592. TIFFescribirDirectorio(c,f,TIFFlugarDirectorio,TIFFlugarPaleta,TIFFlugarImagen);
  593. fclose(f);
  594. return(1);
  595. }
  596.  
  597. void TIFFescribirCabecera(FILE *f)
  598. {
  599. TIFFescribirWord(f,'II');
  600. TIFFescribirWord(f,42);
  601. TIFFescribirLong(f,0L);
  602. }
  603.  
  604. void TIFFescribirDirectorio(IMAGEN *c,FILE *f,long LugarDirectorio,long LugarPaleta,long LugarImagen)
  605. {
  606. unsigned int TIFFtotalTags=0;
  607.  
  608.     /* puntero al fichero para recordar el offset */
  609. switch(c->modo)
  610.     {
  611.     case VIDEOmono:
  612.     /* 7 TAGS */
  613.     TIFFtotalTags=7;
  614.     TIFFescribirWord(f,TIFFtotalTags);
  615.     TIFFescribirTAG(f,ImageWidth,TIFFshort,0L,(long)c->ancho);
  616.     TIFFescribirTAG(f,ImageLength,TIFFshort,0L,(long)c->alto);
  617.     TIFFescribirTAG(f,BitsPerSample,TIFFshort,0L,1L);
  618.     TIFFescribirTAG(f,Compression,TIFFshort,0L,(long)COMPno);
  619.     TIFFescribirTAG(f,PhotometricInterp,TIFFshort,0L,1L);
  620.     TIFFescribirTAG(f,StripOffsets,TIFFlong,1L,LugarImagen);
  621.     TIFFescribirTAG(f,PlanarConfiguration,TIFFshort,1L,1L);
  622.     break;
  623.     case VIDEOega:
  624.     TIFFtotalTags=8;
  625.     TIFFescribirWord(f,TIFFtotalTags);
  626.     TIFFescribirTAG(f,ImageWidth,TIFFshort,0L,(long)c->ancho);
  627.     TIFFescribirTAG(f,ImageLength,TIFFshort,0L,(long)c->alto);
  628.     TIFFescribirTAG(f,BitsPerSample,TIFFshort,1L,4L);
  629.     TIFFescribirTAG(f,Compression,TIFFshort,0L,(long)COMPno);
  630.     TIFFescribirTAG(f,PhotometricInterp,TIFFshort,0L,3L);
  631.     TIFFescribirTAG(f,StripOffsets,TIFFlong,1L,LugarImagen);
  632.     TIFFescribirTAG(f,PlanarConfiguration,TIFFshort,1L,1L);
  633.     TIFFescribirTAG(f,Colormap,TIFFshort,(long)c->colores*6L,LugarPaleta);
  634.     break;
  635.     case VIDEOvga:
  636.     TIFFtotalTags=8;
  637.     TIFFescribirWord(f,TIFFtotalTags);
  638.     TIFFescribirTAG(f,ImageWidth,TIFFshort,0L,(long)c->ancho);
  639.     TIFFescribirTAG(f,ImageLength,TIFFshort,0L,(long)c->alto);
  640.     TIFFescribirTAG(f,BitsPerSample,TIFFshort,1L,8L);
  641.     TIFFescribirTAG(f,Compression,TIFFshort,0L,(long)COMPno);
  642.     TIFFescribirTAG(f,PhotometricInterp,TIFFshort,0L,3L);
  643.     TIFFescribirTAG(f,StripOffsets,TIFFlong,1L,LugarImagen);
  644.     TIFFescribirTAG(f,PlanarConfiguration,TIFFshort,1L,1L);
  645.     TIFFescribirTAG(f,Colormap,TIFFshort,(long)c->colores*6L,LugarPaleta);
  646.     break;
  647.     };
  648.     /* escribir inicio del IFD */
  649. TIFFescribirLong(f,0L);
  650. fseek(f,4l,SEEK_SET);
  651. TIFFescribirLong(f,LugarDirectorio);
  652. }
  653.  
  654. void TIFFescribirTAG(FILE *f,int tag,int tipo,long longitud,long desplazamiento)
  655. {
  656. TIFFescribirWord(f,tag);
  657. TIFFescribirWord(f,tipo);
  658. TIFFescribirLong(f,longitud);
  659. TIFFescribirLong(f,desplazamiento);
  660. }
  661.  
  662. void TIFFescribirImagen(IMAGEN *c,FILE *f)
  663. {
  664.     /* contador líneas */
  665. int i;
  666.     /* buffers */
  667. char p[ANCHO_MAXIMO];
  668. char q[ANCHO_MAXIMO];
  669.     /* salvar imagen */
  670. switch(c->modo)
  671.     {
  672.     case VIDEOmono:
  673.     case VIDEOvga:
  674.         for(i=0;i<c->alto;++i)
  675.             {
  676.             MEMleer(p,i,c);
  677.             TIFFescribirLinea(p,f,c->bytes);
  678.             }
  679.     break;
  680.  
  681.         /* si la imagen es EGA, convertir de plano a pixel */
  682.     case VIDEOega:
  683.         for(i=0;i<c->alto;++i)
  684.             {
  685.             MEMleer(q,i,c);
  686.             EGAdePlanoaPixel(q,p,c->ancho);
  687.             TIFFescribirLinea(p,f,c->bytes);
  688.             }
  689.     break;
  690.     };
  691. }
  692.  
  693. void TIFFescribirLinea(char *p,FILE *f,int bytes)
  694. {
  695. fwrite(p,bytes,1,f);
  696. }
  697.  
  698. void TIFFescribirWord(FILE *f,int n)
  699. {
  700. fputc(n,f);
  701. fputc(n>>8,f);
  702. }
  703.  
  704. void TIFFescribirLong(FILE *f,long n)
  705. {
  706. fputc((int)n,f);
  707. fputc((int)(n>>8),f);
  708. fputc((int)(n>>16),f);
  709. fputc((int)(n>>24),f);
  710. }